import Helloworld from "./Helloworld";
import { isSleeping } from "./Helper";

const { ccclass, property } = cc._decorator;

@ccclass
export default class Persistence extends cc.Component {

    world: CANNON.World;

    @property(cc.Label)
    transformLabel: cc.Label = null;
    times: number = 0;
    autoShoot = false;

    start() {
        this.node.removeFromParent(false);
        cc.game.addPersistRootNode(this.node);
        cc.debug.setDisplayStats(true);

        const p3dm = cc.director.getPhysics3DManager();
        p3dm.enabled = true;
        p3dm.allowSleep = true;
        p3dm.maxSubStep = 100;

        // 表示允许执行多步模拟，建议不要修改，可以通过 maxSubStep 控制最多步进次数
        p3dm.useFixedTime = true;

        // 表示使用物理框架实现的非插值多步模拟
        // 否则将会使用由物理引擎提供的插值多步模拟，可能会导致物理事件不连续
        p3dm['useAccumulator'] = false;

        // 表示使用固定长度机制，使用 p3dm['fixDigits'] 修改位数
        // 比如修改位置的位数长度为 7，p3dm['fixDigits'].position = 7;
        //p3dm['useFixedDigit'] = true;
        //p3dm['fixDigits'].position = 5;
        //p3dm['fixDigits'].rotation = 12;
        //p3dm['physicsWorld'].world.solver.tolerance = 1e-4;
        //if (window['CANNON']) {
        //    this.world = p3dm['physicsWorld']['world'];
        //    this.world.addEventListener('postStep', this.onPostStep.bind(this));
        //    window['CANNON']['Persistence'] = this;
        //}
    }

    update() {
        if (this.autoShoot && isSleeping()) {
            const Canvas = cc.find('Canvas');
            if (Canvas) {
                const hw = Canvas.getComponent(Helloworld);
                if (hw) {
                    this.times++;
                    hw.shoot2();
                }
            }
        }
    }

    onPostStep() {
        const Canvas = cc.find('Canvas');
        if (Canvas) {
            const hw = Canvas.getComponent(Helloworld);
            if (hw) {
                const n = hw.ball.node;
                const body = n.getComponent(cc.Collider3D).shape['sharedBody'].body;
                const wp = body.position;
                const wr = body.quaternion;
                this.transformLabel.string = `${this.times} - ${this.world.stepnumber} - ${this.world.time} \n (${wp.x}, ${wp.y}, ${wp.z}) \n (${wr.x}, ${wr.y}, ${wr.z}, ${wr.w})`                
            }
        }
    }

    onConfigBtn(event: cc.Button) {
        this.node.children[0].active = !this.node.children[0].active;
    }

    onCMathMode(event: cc.Toggle) {
        const int = parseInt(event.node.name);
        if (!isNaN(int)) {
            if (window['CANNON']) window['CANNON']['CMath'].mode = int;
        }
    }

    onCMathDigit(event: cc.EditBox) {
        const int = parseInt(event.string);
        if (!isNaN(int)) {
            if (window['CANNON']) window['CANNON']['CMath'].digit = int;
        }
    }

    onMaxSubSteps(event: cc.EditBox) {
        const int = parseInt(event.string);
        if (!isNaN(int) && int >= 0) {
            cc.director.getPhysics3DManager().maxSubStep = int;
        }
    }

    onAllowSleep(event: cc.Toggle) {
        cc.director.getPhysics3DManager().allowSleep = event.isChecked;
    }

    onFixTimeStep(event: cc.EditBox) {
        const int = parseInt(event.string);
        if (!isNaN(int) && int >= 0) {
            cc.director.getPhysics3DManager().deltaTime = 1 / int;
        }
    }

    onAutoShoot(event: cc.Toggle) {
        this.autoShoot = event.isChecked;
    }

    onPositionDigit(event: cc.EditBox) {
        const int = parseInt(event.string);
        if (!isNaN(int) && int >= 0) {
            cc.director.getPhysics3DManager()['fixDigits']['position'] = int;
        }
    }

    onRotationDigit(event: cc.EditBox) {
        const int = parseInt(event.string);
        if (!isNaN(int) && int >= 0) {
            cc.director.getPhysics3DManager()['fixDigits']['rotation'] = int;
        }
    }

    onIterations(event: cc.EditBox) {
        const int = parseInt(event.string);
        if (!isNaN(int) && int >= 0) {
            cc.director.getPhysics3DManager()['physicsWorld']['world'].solver.iterations = int;
        }
    }

    onToleranceDigit(event: cc.EditBox) {
        const int = parseInt(event.string);
        if (!isNaN(int) && int >= 0) {
            cc.director.getPhysics3DManager()['physicsWorld']['world'].solver.tolerance = Math.pow(10, -int);
        }
    }

}